Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
70.00% covered (warning)
70.00%
7 / 10
CRAP
82.50% covered (warning)
82.50%
33 / 40
IdentifiersMapping
0.00% covered (danger)
0.00%
0 / 1
70.00% covered (warning)
70.00%
7 / 10
27.09
82.50% covered (warning)
82.50%
33 / 40
 __construct
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 getMapping
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getMappedAttribute
0.00% covered (danger)
0.00%
0 / 1
3.33
66.67% covered (warning)
66.67%
2 / 3
 map
0.00% covered (danger)
0.00%
0 / 1
6.03
90.91% covered (success)
90.91%
10 / 11
 getIterator
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 isEmpty
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
4 / 4
 isValid
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
4 / 4
 isUpdated
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 updatedIdentifierCodes
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
5 / 5
 isMappedTo
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 5
<?php
declare(strict_types=1);
/*
 * This file is part of the Akeneo PIM Enterprise Edition.
 *
 * (c) 2018 Akeneo SAS (http://www.akeneo.com)
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace Akeneo\Pim\Automation\FranklinInsights\Domain\IdentifierMapping\Model;
use Akeneo\Pim\Structure\Component\Model\AttributeInterface;
/**
 * Holds the identifiers mapping. Collection of IdentifierMapping entities.
 *
 * @author Julian Prud'homme <julian.prudhomme@akeneo.com>
 */
class IdentifiersMapping implements \IteratorAggregate
{
    /** @var string[] */
    public const FRANKLIN_IDENTIFIERS = [
        'brand',
        'mpn',
        'upc',
        'asin',
    ];
    /** @var IdentifierMapping[] */
    private $mapping;
    /** @var array */
    private $diff;
    /**
     * @param array $mappedAttributes array of AttributeInterface|null, indexed by Franklin identifier codes,
     *                                e.g: ['asin' => $asinAttribute, 'upc' => null, 'brand' => 'null, 'mpn' => null]
     */
    public function __construct(array $mappedAttributes)
    {
        foreach (static::FRANKLIN_IDENTIFIERS as $franklinIdentifier) {
            $this->mapping[$franklinIdentifier] = new IdentifierMapping(
                $franklinIdentifier,
                $mappedAttributes[$franklinIdentifier] ?? null
            );
        }
        $this->diff = [];
    }
    /**
     * @return IdentifierMapping[]
     */
    public function getMapping(): array
    {
        return $this->mapping;
    }
    /**
     * @param string $name
     *
     * @return AttributeInterface|null
     */
    public function getMappedAttribute(string $name): ?AttributeInterface
    {
        if (array_key_exists($name, $this->mapping)) {
            return $this->mapping[$name]->getAttribute();
        }
        return null;
    }
    /**
     * Maps a catalog attribute to a Franklin identifier, and calculates the diff from the previous state.
     * This method is used to mutate the entity.
     *
     * @param string $franklinIdentifierCode
     * @param AttributeInterface|null $attribute
     *
     * @return IdentifiersMapping
     */
    public function map(string $franklinIdentifierCode, ?AttributeInterface $attribute): self
    {
        if (!in_array($franklinIdentifierCode, static::FRANKLIN_IDENTIFIERS)) {
            throw new \InvalidArgumentException(sprintf('Invalid identifier %s', $franklinIdentifierCode));
        }
        $formerAttributeCode =
            (null !== $this->getMappedAttribute($franklinIdentifierCode))
            ? $this->getMappedAttribute($franklinIdentifierCode)->getCode() : null;
        $newAttributeCode = null !== $attribute ? $attribute->getCode() : null;
        if ($formerAttributeCode !== $newAttributeCode) {
            $this->mapping[$franklinIdentifierCode] = new IdentifierMapping($franklinIdentifierCode, $attribute);
            $this->diff[$franklinIdentifierCode] = [
                'former' => $formerAttributeCode,
                'new' => $newAttributeCode,
            ];
        }
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function getIterator(): iterable
    {
        return new \ArrayIterator($this->mapping);
    }
    /**
     * @return bool
     */
    public function isEmpty(): bool
    {
        return empty(array_filter(
            $this->mapping,
            function (IdentifierMapping $identifierMapping) {
                return null !== $identifierMapping->getAttribute();
            }
        ));
    }
    /**
     * @return bool
     */
    public function isValid(): bool
    {
        $validMPNAndBrand = null !== $this->getMappedAttribute('mpn') && null !== $this->getMappedAttribute('brand');
        $validUPC = null !== $this->getMappedAttribute('upc');
        $validASIN = null !== $this->getMappedAttribute('asin');
        return $validASIN || $validUPC || $validMPNAndBrand;
    }
    /**
     * @return bool
     */
    public function isUpdated(): bool
    {
        return !empty($this->diff);
    }
    /**
     * Returns the Franklin identifier codes for which a mapping was updated or deleted (but not added).
     *
     * @return string[]
     */
    public function updatedIdentifierCodes(): array
    {
        return array_keys(
            array_filter(
                $this->diff,
                function (array $value) {
                    return null !== $value['former'];
                }
            )
        );
    }
    /**
     * @param AttributeInterface $referenceAttribute
     *
     * @return bool
     */
    public function isMappedTo(AttributeInterface $referenceAttribute): bool
    {
        foreach ($this->mapping as $identifierMapping) {
            $attribute = $identifierMapping->getAttribute();
            if (null !== $attribute && $referenceAttribute->getCode() === $attribute->getCode()) {
                return true;
            }
        }
        return false;
    }
}